//
//  EasyBaseViewController.m
//  TestDemo
//
//  Created by 张润东 on 2021/8/23.
//

#import "EasyBaseViewController.h"
#import <objc/runtime.h>
#import <objc/message.h>

@interface EasyBaseViewController ()
@property(nonatomic,strong)NSDictionary*titleTextAttributes;
@property(nonatomic,strong)UINavigationBar*cacheNavBar;
@property(nonatomic,strong)UIImage*originBackGroundImage;

@end

@implementation EasyBaseViewController

//load方法会在类第一次加载的时候被调用
//调用的时间比较靠前，适合在这个方法里做方法交换
+ (void)load{
    //方法交换应该被保证，在程序中只会执行一次
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        //获得viewController的生命周期方法的selector
        SEL systemSel = @selector(viewWillAppear:);
        //自己实现的将要被交换的方法的selector
        SEL swizzSel = @selector(swiz_viewWillAppear:);
        //两个方法的Method
        Method systemMethod = class_getInstanceMethod([self class], systemSel);
        Method swizzMethod = class_getInstanceMethod([self class], swizzSel);
        //首先动态添加方法，实现是被交换的方法，返回值表示添加成功还是失败
        BOOL isAdd = class_addMethod(self, systemSel, method_getImplementation(swizzMethod), method_getTypeEncoding(swizzMethod));
        if (isAdd) {
            //如果成功，说明类中不存在这个方法的实现
            //将被交换方法的实现替换到这个并不存在的实现
            class_replaceMethod(self, swizzSel, method_getImplementation(systemMethod), method_getTypeEncoding(systemMethod));
        }else{
            //否则，交换两个方法的实现
            method_exchangeImplementations(systemMethod, swizzMethod);
        }
        //获得viewController的生命周期方法的selector
        SEL systemSel2 = @selector(viewWillDisappear:);
        //自己实现的将要被交换的方法的selector
        SEL swizzSel2 = @selector(swiz_viewWillDisappear:);
        //两个方法的Method
        Method systemMethod2 = class_getInstanceMethod([self class], systemSel2);
        Method swizzMethod2 = class_getInstanceMethod([self class], swizzSel2);
        //首先动态添加方法，实现是被交换的方法，返回值表示添加成功还是失败
        BOOL isAdd2 = class_addMethod(self, systemSel2, method_getImplementation(swizzMethod2), method_getTypeEncoding(swizzMethod2));
        if (isAdd2) {
            //如果成功，说明类中不存在这个方法的实现
            //将被交换方法的实现替换到这个并不存在的实现
            class_replaceMethod(self, swizzSel2, method_getImplementation(systemMethod2), method_getTypeEncoding(systemMethod2));
        }else{
            //否则，交换两个方法的实现
            method_exchangeImplementations(systemMethod2, swizzMethod2);
        }
    });
}



- (void)viewDidLoad {
    [super viewDidLoad];
    //动态属性赋值
    self.automaticallyAdjustsScrollViewInsets = NO;
    if (self.routerParams) {
        [self setRouterPropertys:self.routerParams];
    }
    //标准背景颜色
    self.view.backgroundColor =  [UIColor colorWithRed:((float)((0xf5f5F5 & 0xFF0000) >> 16))/255.0 green:((float)((0xf5f5F5 & 0xFF00) >> 8))/255.0 blue:((float)(0xf5f5F5 & 0xFF))/255.0 alpha:1.0];
    // Do any additional setup after loading the view.
}
-(void)setRouterPropertys:(NSDictionary*)dict{
    unsigned int count;
    objc_property_t* props = class_copyPropertyList([self class], &count);
    for (int i = 0; i < count; i++) {
        objc_property_t property = props[i];
        NSString *name = @(property_getName(property));
        id object = [dict objectForKey:name];
        if (object != nil) {
            // 如果字典中存储了该属性
            [self setValue:object forKey:name];
        }
    }
    free(props);
}


//hook界面出现前 将导航栏原来的navBar复原
- (void)swiz_viewWillAppear:(BOOL)animated{
    [self swiz_viewWillAppear:animated];
    if (self.cacheNavBar) {
        //已创建，有bar缓存
        self.navigationController.navigationBar.backIndicatorImage = self.cacheNavBar.backIndicatorImage;
        self.navigationController.navigationBar.backIndicatorTransitionMaskImage = self.cacheNavBar.backIndicatorTransitionMaskImage;
        self.navigationController.navigationBar.translucent = self.cacheNavBar.translucent;
        self.navigationController.navigationBar.barStyle = self.cacheNavBar.barStyle;
        [self.navigationController.navigationBar setShadowImage:self.cacheNavBar.shadowImage];
        if (self.originBackGroundImage) {
            [self.navigationController.navigationBar setBackgroundImage:self.originBackGroundImage forBarMetrics:UIBarMetricsDefault];
        }
        if (self.titleTextAttributes) {
            [self.navigationController.navigationBar setTitleTextAttributes:self.titleTextAttributes];
        }
        //移除假的navBar
        for (UIView* view in self.navigationController.navigationBar.subviews) {
            if ([view isEqual:self.cacheNavBar]) {
                [view removeFromSuperview];
                break;
            }
        }
    }else{
        //创建展示，无bar缓存，走默认
        UINavigationController *nav = self.navigationController;
        void* (*action)(id,SEL,id) = (void* (*)(id,SEL,id))objc_msgSend;
        SEL sel = NSSelectorFromString(@"navDefaultSetting");
        if (nav && [nav respondsToSelector:sel]) {
            //执行
            action(nav,sel,nil);
        }else{
            //给个默认样式吧!
            [self defaultNavStyle:nav];
            NSLog(@"未实现‘navDefaultSetting’方法!已采用默认样式!");
        }
    }
}

//hook界面消失前 保存navigationBar的状态
- (void)swiz_viewWillDisappear:(BOOL)animated{
    
    [self swiz_viewWillDisappear:animated];
    if (self.navigationController.navigationBar) {
        //界面将要消失时，缓存navBar
        self.cacheNavBar = [UINavigationBar new];
        self.cacheNavBar.backIndicatorImage = self.navigationController.navigationBar.backIndicatorImage;
        self.cacheNavBar.backIndicatorTransitionMaskImage = self.navigationController.navigationBar.backIndicatorTransitionMaskImage;
        self.cacheNavBar.translucent = self.navigationController.navigationBar.translucent;
        self.cacheNavBar.barStyle = self.navigationController.navigationBar.barStyle;
        [self.cacheNavBar setShadowImage:self.navigationController.navigationBar.shadowImage];
        NSDictionary*dict = self.navigationController.navigationBar.titleTextAttributes?:@{};
        self.titleTextAttributes = [NSDictionary dictionaryWithDictionary:dict];
        Class class = NSClassFromString(@"_UIBarBackground");
        for(UIView*subView in self.navigationController.navigationBar.subviews){
            if (class && [subView isKindOfClass:class]) {
                for (UIView * imageV in subView.subviews) {
                    if ([imageV isKindOfClass:[UIImageView class]]) {
                        UIImageView*iamgeView =(UIImageView*)imageV;
                        if (iamgeView.image) {
                            self.originBackGroundImage = iamgeView.image;
                            break;
                        }
                    }
                }
            }
        }
        [self.navigationController.navigationBar addSubview:self.cacheNavBar];
    }
}

- (UIImage*)imageWithColor:(UIColor *)color{
    CGRect rect = CGRectMake(0.0f, 0.0f, 1.0f, 1.0f);
    UIGraphicsBeginImageContext(rect.size);
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextSetFillColorWithColor(context, color.CGColor);
    CGContextFillRect(context, rect);
    UIImage* image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    NSData* imageData = UIImageJPEGRepresentation(image, 1.0f);
    image = [UIImage imageWithData:imageData];
    return image;
}


//兜底的默认样式
-(void)defaultNavStyle:(UINavigationController*)nav{
    nav.navigationBar.barStyle = UIBarStyleDefault;//状态栏黑色  UIBarStyleBlack:状态栏白色
    [nav.navigationBar setBackgroundImage:[self imageWithColor:[UIColor whiteColor]] forBarMetrics:UIBarMetricsDefault];//背景颜色
    [nav.navigationBar setShadowImage:[UIImage new]];//底部细线消失术
    [nav.navigationBar setTranslucent:NO];//是否半透明标识
    [nav.navigationBar setTitleTextAttributes:@{NSForegroundColorAttributeName:[UIColor blackColor],NSFontAttributeName:[UIFont systemFontOfSize:19]}];//title文字颜色与大小
    nav.automaticallyAdjustsScrollViewInsets = NO;
}

//防止没有属性时的崩溃,心理安慰,保险下
-(void)setValue:(id)value forUndefinedKey:(NSString *)key{
    
}



@end
